﻿#include "GY_TreeView.h"
#include <QMessageBox>
#include <QTableWidgetItem>
#include <QTime>
#include <QMap>
#include <QVector>
#include <QModelIndex>
#include <QMouseEvent>
#include <QApplication>
#include <QMimeData>
#include <QPainter>
#include <QDrag>
#include <QDebug>

GY_TreeView::GY_TreeView(QWidget *parent)
    : QTreeView(parent)
{
    this->setModel(new QStandardItemModel);
    connect(this,&GY_TreeView::clicked,this,&GY_TreeView::receiveClicked); //单击接收事件
    connect(this,&GY_TreeView::expanded,this,&GY_TreeView::receiveExpend); //节点展开接收事件
    connect(this,&GY_TreeView::collapsed,this,&GY_TreeView::receiveCollapsed); //节点关闭展开事件
    m_isCheckable = false;
}

/**
 * @brief filter 筛选文本
 * @param str 文本内容
 */
void GY_TreeView::filter(QString str)
{
    QList<QStandardItem*> resultlist = ((QStandardItemModel*)this->model())->findItems(str,Qt::MatchContains | Qt::MatchRecursive);
    auto row = ((QStandardItemModel*)this->model())->rowCount();
    for(int i=0;i<row;i++){
        auto pItem = ((QStandardItemModel*)this->model())->item(i);
        bool bHide = checkResultListIsHidden(pItem,resultlist);
        if(bHide){
            bHide = !resultlist.contains(pItem);
        }
        this->setRowHidden(pItem->row(),((QStandardItemModel*)this->model())->indexFromItem(pItem->parent()),bHide);
    }
}

/**
 * @brief checkContainStr 检查子节点是否包含在筛选的节点集中
 * @param pItem 节点item
 * @param resultlist 筛选出的节点集
 * @return
 */
bool GY_TreeView::checkResultListIsHidden(QStandardItem *pItem, QList<QStandardItem *> resultlist)
{
    QModelIndex parentIndex = ((QStandardItemModel*)this->model())->indexFromItem(pItem->parent());
    if(pItem->hasChildren()){
        bool bHide = true;
        for(auto i = 0; i < pItem->rowCount(); i++){
            if(!checkResultListIsHidden(pItem->child(i),resultlist)){
               bHide = false;
            }
        }
        if(bHide){
            bHide = !resultlist.contains(pItem);
        }
        this->setRowHidden(pItem->row(),parentIndex,bHide);
        return bHide;
    }else{
        this->setRowHidden(pItem->row(),parentIndex,!resultlist.contains(pItem));
        return this->isRowHidden(pItem->row(),parentIndex);
    }
}

/**
 * @brief setColumnCount 设置列数
 * @param columnCount 添加的列数
 */
void GY_TreeView::setColumnCount(const int columnCount)
{
    if(columnCount<=0) //设置0列及以下为无效
    {
        return;
    }
    if(!((QStandardItemModel*)this->model())->columnCount()){ //如果列表为空
        ((QStandardItemModel*)this->model())->setColumnCount(columnCount);
        QStringList headNames; //创建表名
        for(int i=0; i<columnCount;i++)
        {
            headNames << QString("标题%1").arg(i+1);
        }
        ((QStandardItemModel*)this->model())->setHorizontalHeaderLabels(headNames); //将表名导入列表中
//        this->setModel(((QStandardItemModel*)this->model())); //添加((QStandardItemModel*)this->model())到treeview中
    }
    else //如果列表存在数据
    {
        QStandardItemModel *pNewModel = new QStandardItemModel(this); //创建一个新的model指针
        pNewModel->setColumnCount(columnCount);
        //设置已有列名
        QStringList headNames;
        for(int i=0;i<columnCount;i++)
        {
            if(i<((QStandardItemModel*)this->model())->columnCount())
            {
                headNames<<((QStandardItemModel*)this->model())->horizontalHeaderItem(i)->text();
            }
            else
            {
                headNames<<QString("标题%1").arg(i+1);
            }
        }
        pNewModel->setHorizontalHeaderLabels(headNames); //将列名导入列表中

        //设置已有数据
        for(int i=0;i<((QStandardItemModel*)this->model())->rowCount();i++)
        {
            QList<QStandardItem*> rowItems;
            QVariant rowId;
            for(int j=0;j<columnCount;j++)
            {
                //设置
                QStandardItem* pNewRowItem = new QStandardItem;
                //判定设置的列数是否少于原列数
                if(j<((QStandardItemModel*)this->model())->columnCount())
                {
                    QStandardItem* pOldRowItem = ((QStandardItemModel*)this->model())->item(i,j);
                    pNewRowItem->setData(pOldRowItem->data());
                    pNewRowItem->setText(pOldRowItem->text()); //后期添加按键，则不能用text格式，需判断一下
                    if(j==0)
                    {
                        rowId=pOldRowItem->data(Qt::UserRole);
                        pNewRowItem->setData(rowId,Qt::UserRole);
                        pNewRowItem->setIcon(m_IconIdMap.value(rowId));
                    }
                }
                else
                {
                    m_TreeNodeInfo.value(rowId)->nodeDatas.append(QVariant());
                }
                rowItems<< pNewRowItem; //将新行数据依次传入list容器中
            }
            if(rowItems.size()>0)
            {
                //更改存储的节点信息
                if(m_TreeNodeInfo.contains(rowId))
                {
                    m_TreeNodeInfo.value(rowId)->pNodeItem=rowItems[0]; //将rowid设为父节点
                    //移除多余数据
                    for(int k=rowItems.size();k<m_TreeNodeInfo.value(rowId)->nodeDatas.size();k++)
                    {
                         m_TreeNodeInfo.value(rowId)->nodeDatas.removeLast();
                    }
                }

                //递归挂接下一级节点
                QStandardItem* pTempItem = ((QStandardItemModel*)this->model())->item(i);
                if(pTempItem->hasChildren())
                {
                    moveItems(rowItems[0],pTempItem,pNewModel->columnCount());
                }
            }
            pNewModel->appendRow(rowItems);
        }
        this->setModel(pNewModel);
        connect(((QStandardItemModel*)this->model()),&QStandardItemModel::itemChanged,this,&GY_TreeView::ItemChanged);
    }
}

/**
 * @brief moveItems 将旧列表items赋给新列表
 * @param pDetItem 目的item
 * @param pSrcItem 源item
 * @param columnCount 目的列表列数
 */
void GY_TreeView::moveItems(QStandardItem* const pDetItem, const QStandardItem *pSrcItem,const int columnCount)
{
    for(int i=0;i<pSrcItem->rowCount();i++)
    {
        QList<QStandardItem*> rowItems;
        QVariant rowId;
        for(int j=0;j<columnCount;j++)
        {
            QStandardItem* pNewRowItem = new QStandardItem;
            if(j<((QStandardItemModel*)this->model())->columnCount())
            {
                QStandardItem* pOldRowItem = pSrcItem->child(i,j);
                pNewRowItem->setData(pOldRowItem->data());
                pNewRowItem->setText(pOldRowItem->text());
                if(j==0)
                {
                    rowId=pOldRowItem->data(Qt::UserRole);
                    pNewRowItem->setData(pOldRowItem->data(Qt::UserRole),Qt::UserRole);
                    pNewRowItem->setIcon(m_IconIdMap.value(rowId));
                }
            }
            rowItems<<pNewRowItem;
        }
        if(rowItems.size()>0)
        {
            //更改存储的节点信息
            if(m_TreeNodeInfo.contains(rowId))
            {
                m_TreeNodeInfo.value(rowId)->pNodeItem=rowItems[0];
                //移除多余数据
                for(int k=rowItems.size();k<m_TreeNodeInfo.value(rowId)->nodeDatas.size();k++)
                {
                    m_TreeNodeInfo.value(rowId)->nodeDatas.removeLast();
                }
            }
            //递归挂接下一级节点
            QStandardItem* pTempItem = pSrcItem->child(i);
            if(pTempItem->hasChildren())
            {
                moveItems(rowItems[0],pTempItem,columnCount);
            }
        }
        pDetItem->appendRow(rowItems);
    }
}

/**
 * @brief addColumn 添加列数
 * @param columnName 添加的列名
 */
void GY_TreeView::addColumn(const QString &columnName)
{
    if(columnName==nullptr) //设置列名为空无效
    {
        return;
    }
    int column = ((QStandardItemModel*)this->model())->columnCount();
    setColumnCount(column+1);
    QStandardItem* pItem = new QStandardItem(columnName);
    ((QStandardItemModel*)this->model())->setHorizontalHeaderItem(column,pItem); //将添加的列名放在列表后
}

/**
 * @brief insterColumn 插入列
 * @param index 插入在第几列
 * @param columnName 插入的列名
 * @return 返回插入列是否成功
 */
bool GY_TreeView::insterColumn(const int index, const QString &columnName)
{
    if(!((QStandardItemModel*)this->model()) || index<0 || index>((QStandardItemModel*)this->model())->columnCount()){
        return false;
    }
    else
    {
        QList<QStandardItem*> listItem;
        for(int i=0;i<((QStandardItemModel*)this->model())->rowCount();i++)
        {
            QStandardItem* pRowItem = ((QStandardItemModel*)this->model())->item(i);
            QVariant rowId = itemFindId(pRowItem); //找到对应的id号
            m_TreeNodeInfo.value(rowId)->nodeDatas.insert(index,QVariant()); //更新map数据表
            if(((QStandardItemModel*)this->model())->hasChildren())
            {
                insertChildColumn(index,pRowItem);
            }
            listItem<<pRowItem;
        }
        ((QStandardItemModel*)this->model())->insertColumn(index,listItem);
        QStandardItem* pitem = new QStandardItem(columnName);
        ((QStandardItemModel*)this->model())->setHorizontalHeaderItem(index,pitem);
        return true;
    }
}

/**
 * @brief insertChildColumn 循环插入空白列
 * @param pItem 每行的item
 */
void GY_TreeView::insertChildColumn(const int index, QStandardItem * const pItem)
{
    if(!pItem)
    {
        return;
    }
    QList<QStandardItem*> listItems;
    pItem->insertColumn(index,listItems);
    for(int i=0;i<pItem->columnCount();i++)
    {
        QStandardItem* pChildItem = pItem->child(i);
        QVariant rowId = itemFindId(pChildItem);
        m_TreeNodeInfo.value(rowId)->nodeDatas.insert(index,QVariant());
        listItems<<pChildItem;
        insertChildColumn(index,pChildItem);
    }
}

/**
 * @brief deleteColumn 删除列
 * @param index 删除的第几列
 * @return 返回删除列是否成功
 */
bool GY_TreeView::deleteColumn(const int index)
{
    if(((QStandardItemModel*)this->model())==nullptr ||index<0 || index>((QStandardItemModel*)this->model())->columnCount())
    {
        return false;
    }
    QStandardItem *pitem = ((QStandardItemModel*)this->model())->invisibleRootItem();
    pitem->takeColumn(index);
    for(int i=0;i<((QStandardItemModel*)this->model())->rowCount();i++)
    {
        QStandardItem* pRowItem = ((QStandardItemModel*)this->model())->item(i);
        QVariant rowId = itemFindId(pRowItem); //找到对应的id号
        m_TreeNodeInfo.value(rowId)->nodeDatas.removeAt(index); //更新map数据表
        if(((QStandardItemModel*)this->model())->hasChildren())
        {
            deleteChildColumn(index,pRowItem);
        }
    }
    return true;
}

/**
 * @brief deleteChildColumn  循环删除指定列
 * @param index  索引删除第几列
 * @param pItem  每行对应的item
 */
void GY_TreeView::deleteChildColumn(const int index, QStandardItem * const pItem)
{
    if(!pItem)
    {
        return;
    }
    pItem->takeColumn(index);
    for(int i=0;i<pItem->columnCount();i++)
    {
        QStandardItem* pChildItem = pItem->child(i);
        QVariant rowId = itemFindId(pChildItem);
        m_TreeNodeInfo.value(rowId)->nodeDatas.removeAt(index); //更新map数据表
        deleteChildColumn(index,pChildItem);
    }
}

/**
 * @brief setColumnHeadName  修改列名
 * @param nameList  要修改的列名集
 */
void GY_TreeView::setColumnHeadName(const QStringList &nameList)
{
    if(nameList.size()<0)
    {
        return;
    }
    QStringList headNames;
    for(int i=0;i<((QStandardItemModel*)this->model())->columnCount();i++)
    {
        if(i<nameList.size())
        {
            headNames<< nameList.at(i);
        }
        else
        {
            headNames<< ((QStandardItemModel*)this->model())->horizontalHeaderItem(i)->text();
        }
    }
    ((QStandardItemModel*)this->model())->setHorizontalHeaderLabels(headNames); //将列名导入列表中
}

/**
 * @brief setColumnHeadName  修改某一列列名
 * @param index  要修改名字在第几列
 * @param headName  要修改成的名字
 */
void GY_TreeView::setColumnHeadName(const int index, const QString &headName)
{
    QStandardItem* pitem = new QStandardItem(headName);
    ((QStandardItemModel*)this->model())->setHorizontalHeaderItem(index,pitem);
}

/**
 * @brief addRowData  添加行数据
 * @param id 行Id
 * @param rowData 行数据
 * @param nodeParentId 父级Id
 * @param iconType 设置图标类型
 * @return 返回添加是否成功
 */
bool GY_TreeView::addRowData(const QVariant &rowId, const QVector<QVariant> &rowData, const QVariant &parentId, const QVariant &iconType)
{
    if(m_TreeNodeInfo.contains(rowId)||!rowData.size()||!((QStandardItemModel*)this->model())||!((QStandardItemModel*)this->model())->columnCount())
    {
        return false;
    }
    QList<QStandardItem*> rowItems;
    int count = ((QStandardItemModel*)this->model())->columnCount();
    for(int i=0;i<count;i++)
    {
        QStandardItem* pItem=new QStandardItem; //创建新节点
        pItem->setFlags(pItem->flags() | Qt::ItemIsEditable); //设置该节点具有可编辑属性
        if(i<rowData.size()) //如果插入的行数据的数量大于列数
        {
            pItem->setData(rowData[i].toString());
            pItem->setText(rowData[i].toString());
            //对每行第一列数据设置id和子节点
            if(i==0)
            {
                pItem->setData(rowId,Qt::UserRole);
                Tree_Node_Info* pNodeInfo=new Tree_Node_Info{rowId,parentId,pItem,rowData,iconType};
                m_TreeNodeInfo.insert(rowId,pNodeInfo);
                if(!m_nodeNameList.contains(pItem->text()))
                {
                    m_nodeNameList.append(pItem->text());
                }
                setNodeIconType(rowId,iconType);
            }
        }
        else
        {
            m_TreeNodeInfo.value(rowId)->nodeDatas.append(QVariant());
        }
        //文本居中
        pItem->setTextAlignment(Qt::AlignCenter);

        rowItems<<pItem;
    }
    //判定顶层节点是否存在
    if(m_TreeNodeInfo.contains(parentId))
    {
        m_TreeNodeInfo.value(parentId)->pNodeItem->appendRow(rowItems);
    }
    else //若不存在，则直接在根结点后添加一行数据
    {
        ((QStandardItemModel*)this->model())->appendRow(rowItems);
    }
    return true;
}

/**
 * @brief insterRowData 插入行数据
 * @param rowId 行id
 * @param rowData 添加的行数据
 * @param index 引索第几个
 * @param parentId 父级Id
 * @param iconType 设置图标类型
 * @return 返回插入行数据是否成功
 */
bool GY_TreeView::insterRowData(const QVariant &rowId, const QVector<QVariant> &rowData, const int index, const QVariant &parentId, const QVariant iconType)
{
    if(m_TreeNodeInfo.contains(rowId)||!rowData.size()||!((QStandardItemModel*)this->model())||!((QStandardItemModel*)this->model())->columnCount())
    {
        return false;
    }
    QList<QStandardItem*> rowItems;
    int count = ((QStandardItemModel*)this->model())->columnCount();
    for(int i=0;i<count;i++)
    {
        QStandardItem* pItem=new QStandardItem;
        pItem->setFlags(pItem->flags() | Qt::ItemIsEditable); //该节点具有可编辑属性
        if(i<rowData.size())
        {
            pItem->setData(rowData[i]);
            pItem->setText(rowData[i].toString());
            //对每行第一列数据设置id和子节点
            if(i==0)
            {
                pItem->setData(rowId,Qt::UserRole);
                Tree_Node_Info* pNodeInfo=new Tree_Node_Info{rowId,parentId,pItem,rowData,iconType};
                m_TreeNodeInfo.insert(rowId,pNodeInfo);
                if(!m_nodeNameList.contains(pItem->text()))
                {
                    m_nodeNameList.append(pItem->text());
                }
                setNodeIconType(rowId,iconType);
            }
        }
        else
        {
            m_TreeNodeInfo.value(rowId)->nodeDatas.append("");
        }

        rowItems<<pItem;
    }
    //判定顶层节点是否存在
    if(m_TreeNodeInfo.contains(parentId))
    {
        QStandardItem* pItem = m_TreeNodeInfo.value(parentId)->pNodeItem;
        if(index<pItem->rowCount()){
            pItem->insertRow(index,rowItems);
        }
        else
        {
            pItem->appendRow(rowItems);
        }
    }
    else //若不存在，则直接在根结点后在对应索引处插入一行数据
    {
        if(index<((QStandardItemModel*)this->model())->rowCount()){
            ((QStandardItemModel*)this->model())->insertRow(index,rowItems);
        }
        else
        {
            ((QStandardItemModel*)this->model())->appendRow(rowItems);
        }
    }
    return true;
}

/**
 * @brief deleteRow  删除指定行
 * @param id 删除行的id号
 * @return 返回删除是否成功
 */
bool GY_TreeView::deleteRow(const QVariant &rowId)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return false;
    }
    QStandardItem* pItem = m_TreeNodeInfo.value(rowId)->pNodeItem;

    //判定是否是顶层节点
    if(!pItem->parent())
    {
        ((QStandardItemModel*)this->model())->removeRow(pItem->index().row());
    }
    else
    {
        pItem->parent()->removeRow(pItem->index().row());
    }

    m_nodeNameList.removeOne(m_TreeNodeInfo.value(rowId)->nodeDatas.at(0).toString());
    delete m_TreeNodeInfo[rowId];
    m_TreeNodeInfo.remove(rowId);
    m_IconIdMap.remove(rowId);
    if(m_checkedRowIds.contains(rowId))
    {
        m_checkedRowIds.removeOne(rowId);
    }
    if(m_checkRowDatas.contains(rowId))
    {
        m_checkRowDatas.remove(rowId);
    }
    if(m_getselectRowIdsVec.contains(rowId))
    {
        m_getselectRowIdsVec.removeOne(rowId);
    }

    return true;
}

/**
 * @brief deleteChildRowIdList 删除该节点下的所有子节点
 * @param rowId 行id
 * @return 返回删除是否成功
 */
void GY_TreeView::deleteChildRowIdList(const QVariant &rowId)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return;
    }
    QVector<QVariant> childIdsVec = getRowChildIds(rowId);
    for(int i=0;i<childIdsVec.size();i++)
    {
        m_nodeNameList.removeOne(m_TreeNodeInfo.value(childIdsVec[i])->nodeDatas.at(0).toString());
        m_IconIdMap.remove(childIdsVec[i]);
        deleteRow(childIdsVec[i]);
        delete m_TreeNodeInfo[childIdsVec[i]];
        m_TreeNodeInfo.remove(childIdsVec[i]);
    }
}

/**
 * @brief clearData 清除所有数据
 */
void GY_TreeView::clearData()
{
    if(!((QStandardItemModel*)this->model()) || m_TreeNodeInfo.isEmpty())
    {
        return;
    }
    ((QStandardItemModel*)this->model())->clear();
    //依然存在内存泄露
    for(auto& it : m_TreeNodeInfo){
        delete it;
        it = nullptr;
    }

    m_TreeNodeInfo.clear();
    m_nodeNameList.clear();
    m_checkedRowIds.clear();
    m_checkRowDatas.clear();
    m_getselectRowIdsVec.clear();
    m_doubleClickedId = "";
    m_selectRowId = "";
    m_oldName = "";
    m_checkedId = "";
    m_regExp = "";

}

/**
 * @brief setRowData  修改行数据
 * @param rowId  修改行id
 * @param rowData  要修改的数据
 * @return 是否修改成功
 */
bool GY_TreeView::setRowData(const QVariant &rowId, const QVector<QVariant> &rowData)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return false;
    }

    QStandardItem* pNodeItem = m_TreeNodeInfo.value(rowId)->pNodeItem;
    QStandardItem* pParentItem = new QStandardItem;
    QVariant nodeParentId;
    if(pNodeItem->parent()){ //判断是否有父节点
        pParentItem = pNodeItem->parent();
        nodeParentId = m_TreeNodeInfo.value(rowId)->nodeParentId; //记录父节点
    }
    else{
        pParentItem = ((QStandardItemModel*)this->model())->invisibleRootItem();
    }

    QList<QStandardItem*> rowItems;
    for(int j=0;j<((QStandardItemModel*)this->model())->columnCount();j++)
    {
        QStandardItem* pNewRowItem = pParentItem->child(pNodeItem->index().row(),j);
        pNewRowItem->setFlags(pNewRowItem->flags() | Qt::ItemIsEditable); //该节点具有可编辑属性
        if(j<rowData.size())
        {
            pNewRowItem->setData(rowData.at(j));
            pNewRowItem->setText(rowData.at(j).toString()); //后期添加按键，则不能用text格式，需判断一下
            if(j==0)
            {
                pNewRowItem->setData(rowData.at(j),Qt::UserRole);
                QVariant iconType = m_TreeNodeInfo.value(rowId)->nodeIconType;
                Tree_Node_Info* pNodeInfo=new Tree_Node_Info{rowId,nodeParentId,pNewRowItem,rowData,iconType}; //存入新节点
                m_TreeNodeInfo.insert(rowId,pNodeInfo);
                pNewRowItem->setIcon(m_IconIdMap.value(rowId));
            }
        }
        else
        {
            pNewRowItem->setData(QVariant());
            pNewRowItem->setText(QVariant().toString());
        }
        rowItems<<pNewRowItem;
    }
    return true;
}

/**
 * @brief setCellData  修改单元格数据
 * @param id  修改的行id
 * @param columnIndex  修改第几列
 * @param cellData  要修改的数据
 * @return 是否修改成功
 */
bool GY_TreeView::setCellData(const QVariant &id, const int columnIndex, const QVariant &cellData)
{
    if(!m_TreeNodeInfo.contains(id) || columnIndex<0 || columnIndex>=((QStandardItemModel*)this->model())->columnCount())
    {
        return false;
    }
    QStandardItem* pNodeItem = m_TreeNodeInfo.value(id)->pNodeItem;
    QStandardItem* pParentItem = nullptr;
    QVariant nodeParentId;
    if(pNodeItem->parent()){
        pParentItem = pNodeItem->parent();
        nodeParentId = m_TreeNodeInfo.value(id)->nodeParentId;
    }
    else{
        pParentItem = ((QStandardItemModel*)this->model())->invisibleRootItem();
    }

    QStandardItem *pNewNodeItem = pParentItem->child(pNodeItem->index().row(),columnIndex);
    if(pNewNodeItem==nullptr) return false;
    pNewNodeItem->setFlags(pNewNodeItem->flags() | Qt::ItemIsEditable); //该节点具有可编辑属性
    pNewNodeItem->setData(cellData);
    pNewNodeItem->setText(cellData.toString());
    QVector<QVariant> rowData;
    for(int i=0;i< m_TreeNodeInfo.value(id)->nodeDatas.size();i++)
    {
        QVariant newData = m_TreeNodeInfo.value(id)->nodeDatas.at(i);
        if(i==columnIndex)
        {
            newData = cellData;
        }
        rowData<<newData;

        if(i==0)
        {
            pNewNodeItem->setData(cellData,Qt::UserRole);
            pNewNodeItem->setIcon(m_IconIdMap.value(id));
        }
    }
    QVariant iconType = m_TreeNodeInfo.value(id)->nodeIconType;
    delete m_TreeNodeInfo[id];
    m_TreeNodeInfo.remove(id); //移出原来的节点
    Tree_Node_Info* pNodeInfo=new Tree_Node_Info{id,nodeParentId,pNewNodeItem,rowData,iconType}; //存入新节点
    m_TreeNodeInfo.insert(id,pNodeInfo);
    return  true;
}

/**
 * @brief getRowData  通过id获取行数据
 * @param id  要获取的节点id
 * @return id对应的行数据
 */
QVector<QVariant> GY_TreeView::getRowData(const QVariant &id)
{
    QVector<QVariant> rowData;
    if(!m_TreeNodeInfo.contains(id)|| !((QStandardItemModel*)this->model()))
    {
        return rowData<<QVariant();
    }
//    QStandardItem* pItem = m_TreeNodeInfo.value(id)->pNodeItem;
//    setCellData(id,0,pItem->text());
    rowData = m_TreeNodeInfo.value(id)->nodeDatas;
    return rowData;
}

/**
 * @brief getRowData  通过parentId获取行数据
 * @param index  引索要获取第几行
 * @param parentId  父节点id
 * @return 索引的行数据
 */
QVector<QVariant> GY_TreeView::getRowDatas(const int index, const QVariant &parentId)
{
    QVector<QVariant> rowData = QVector<QVariant>()<<"错误";
    if(!m_TreeNodeInfo.contains(parentId) ||index<0 ||index>m_TreeNodeInfo.value(parentId)->pNodeItem->rowCount())
    {
        return rowData;
    }
    QStandardItem* pParentItem = m_TreeNodeInfo.value(parentId)->pNodeItem;
    rowData.clear();
    for(int i=0;i<((QStandardItemModel*)this->model())->columnCount();i++)
    {
        rowData << pParentItem->child(index,i)->data();
    }
    return rowData;
}

/**
 * @brief getCellData  获取单元格数据
 * @param id  节点id
 * @param columnIndex  索引第几列
 * @param data  单元格的数据
 * @return 返回是否获取成功
 */
bool GY_TreeView::getCellData(const QVariant &id, const int columnIndex, QVariant &data)
{
    if(!m_TreeNodeInfo.contains(id) || columnIndex<0 || columnIndex>=((QStandardItemModel*)this->model())->columnCount())
    {
        return false;
    }
    data = m_TreeNodeInfo.value(id)->nodeDatas.at(columnIndex);
    return true;
}

/**
 * @brief getAllRowIds 获取所有行Id
 * @param rowId 行Id
 * @return 返回所有Id集
 */
QVector<QVariant> GY_TreeView::getAllRowIds()
{
    QVector<QVariant> rowIds;
    foreach(Tree_Node_Info* treeInfo, m_TreeNodeInfo)
    {
        rowIds<< treeInfo->nodeId;
    }
    return rowIds;
}

/**
 * @brief addIconType 添加图标类型
 * @param iconType 图标类型
 * @param icon 图标
 * @return 是否添加成功
 */
bool GY_TreeView::addIconType(const QVariant &iconType, const QIcon &icon)
{
    if(m_IconTypeMap.contains(iconType)) //如果图标类型存在
    {
        return false;
    }
    m_IconTypeMap.insert(iconType,icon); //记录图标和类型的关联信息
    return true;
}

/**
 * @brief setNodeIconType 设置id对应的图标
 * @param id 行id
 * @param iconType 图标类型
 * @return 是否设置成功
 */
bool GY_TreeView::setNodeIconType(const QVariant &id, const QVariant &iconType)
{
    if(!m_TreeNodeInfo.contains(id) || !m_IconTypeMap.contains(iconType)) //如果行id或者图标类型不存在
    {
        return false;
    }
    QStandardItem* pItem = m_TreeNodeInfo.value(id)->pNodeItem;
    Tree_Node_Info* pNodeInfo=new Tree_Node_Info{id,m_TreeNodeInfo.value(id)->nodeParentId,pItem,m_TreeNodeInfo.value(id)->nodeDatas,iconType}; //存入新节点
    delete m_TreeNodeInfo[id];
    m_TreeNodeInfo.insert(id,pNodeInfo);
    QIcon icon = m_IconTypeMap.value(iconType); // 获取类型对应的图标
    m_IconIdMap.insert(id,icon); //记录图标和id的关联信息
    pItem->setIcon(icon);
    return true;
}

/**
 * @brief getDoubleClickedId 获取双击选择行id
 * @return 双击的行id
 */
QVariant GY_TreeView::getDoubleClickedId()
{
    return m_doubleClickedId;
}

/**
 * @brief getSelecRowId  获取选择行id
 * @return  多选下返回选中的第一行
 */
QVariant GY_TreeView::getSelectRowId()
{
    return m_selectRowId;
}

/**
 * @brief getSelectRowIds 获取选择行id
 * @return  单选时返回一个id
 */
QVector<QVariant> GY_TreeView::getSelectRowIds()
{
    QModelIndexList selected = this->selectionModel()->selectedRows(); //获取选中行
    QVector<QVariant> selectedRowIds;
    for(int i=0;i<selected.size();i++)
    {
        QStandardItem* pItem = ((QStandardItemModel*)this->model())->itemFromIndex(selected.at(i));
        QVariant rowId = itemFindId(pItem);
        selectedRowIds<< rowId;
    }
    return  selectedRowIds;
}

/**
 * @brief setRowSelectState 设置行选择状态
 * @param rowId 节点ID
 * @param isSelect 该行是否选择
 * @return 是否设置成功
 */
bool GY_TreeView::setRowSelectState(const QVector<QVariant> &rowIdsVec, const bool isSelect)
{
    if(rowIdsVec.isEmpty() || !isSelect)
    {
        return false;
    }
    clearSelection(); //清理之前选中项
    for (int i=0;i<rowIdsVec.size();i++)
    {
        if(m_TreeNodeInfo.contains(rowIdsVec[i]))
        {
            m_selectRowId = rowIdsVec[i];
            QStandardItem* pItem = m_TreeNodeInfo.value(rowIdsVec[i])->pNodeItem;
            QModelIndex index = ((QStandardItemModel*)this->model())->indexFromItem(pItem);
            this->selectionModel()->select(index,QItemSelectionModel::Select | QItemSelectionModel::Rows);
        }
    }
    return true;
}

/**
 * @brief getExpentState 获取节点展开状态
 * @param rowId 行ID
 * @return 返回是否展开
 */
bool GY_TreeView::getExpentState(const QVariant &rowId)
{
    if(!m_TreeNodeInfo.contains(rowId) || !((QStandardItemModel*)this->model()))
    {
        return false;
    }
    QStandardItem* pItem = m_TreeNodeInfo.value(rowId)->pNodeItem;
    QModelIndex index = pItem->index();
    return this->isExpanded(index);
}

/**
 * @brief setRowExpendState  设置行单层展开模式
 * @param rowId  第几个id
 * @param isExpend  是否展开
 * @return 返回是否展开该行
 */
bool GY_TreeView::setRowExpendState(const QVariant &rowId,const bool isExpend)
{
    if(!m_TreeNodeInfo.contains(rowId) || !((QStandardItemModel*)this->model()))
    {
        return false;
    }
    QStandardItem* pItem = m_TreeNodeInfo.value(rowId)->pNodeItem;
    QModelIndex index = pItem->index();
    this->setExpanded(index,isExpend); //设置是否展开
    return true;
}

/**
 * @brief setRowExpendAllChildState 设置行全部展开模式
 * @param rowId 第几个id
 * @param isExpend 是否展开
 * @return 返回是否展开该行
 */
bool GY_TreeView::setRowExpendAllChildState(const QVariant &rowId, const bool isExpend)
{
    if(!m_TreeNodeInfo.contains(rowId) || !((QStandardItemModel*)this->model()))
    {
        return false;
    }
    QStandardItem* pItem = m_TreeNodeInfo.value(rowId)->pNodeItem;
    treeAllChildExpend(pItem,isExpend); //展开该id所有子节点
    treeTopPareentExpent(pItem,isExpend); //递归展开该id父节点
    return true;
}

/**
 * @brief treeAllChildExpend 所有子节点展开
 * @param pItem 子节点的item
 * @param isExpend 是否展开
 */
void GY_TreeView::treeAllChildExpend(QStandardItem *pItem, bool isExpend)
{
    if(nullptr==pItem) //判断item是否存在，或者是否展开
    {
        return;
    }
    if(pItem->hasChildren())
    {
        QModelIndex index = pItem->index();
//        this->expand(index); //展开该item
        this->setExpanded(index,isExpend); //设置是否展开
        for(int i=0;i<pItem->rowCount();i++)
        {
            QStandardItem* pNewItem = pItem->child(i);
            treeAllChildExpend(pNewItem,isExpend);
        }
    }
}

/**
 * @brief treeTopPareentExpent 递归至顶层父节点
 * @param pItem 父节点item
 * @param isExpend 是否展开
 */
void GY_TreeView::treeTopPareentExpent(QStandardItem *pItem, bool isExpend)
{
    if(nullptr==pItem || !isExpend)
    {
        return;
    }
    QModelIndex index = pItem->index();
//    this->expand(index);
    this->setExpanded(index,isExpend); //设置是否展开
    if(pItem->parent()) //判断父节点是否存在
    {
        treeTopPareentExpent(pItem->parent(),isExpend); //递归查找至最顶层父节点
    }
}

/**
 * @brief getRowChildIds 通过行id获取其下所有子节点
 * @param rowId 行id
 * @return 返回该节点的所有子节点
 */
QVector<QVariant> GY_TreeView::getRowChildIds(const QVariant &rowId)
{
    QVector<QVariant> childRowIds;
    if(m_TreeNodeInfo.contains(rowId))
    {
        QStandardItem* pItem = m_TreeNodeInfo.value(rowId)->pNodeItem;
        getTreeAllChildIds(pItem,childRowIds);
    }
    return childRowIds;
}

/**
 * @brief getTreeAllChildIds 获取pitem对应子节点
 * @param pItem 节点
 * @param childIdsVec 子节点
 */
void GY_TreeView::getTreeAllChildIds(QStandardItem *pItem, QVector<QVariant> &childIdsVec)
{
    if(nullptr==pItem) //判断item是否存在
    {
        return;
    }
    if(pItem->hasChildren())
    {
        for(int i=0;i<pItem->rowCount();i++)
        {
            QStandardItem* pNewItem = pItem->child(i);
//            childIdsVec << itemFindId(pNewItem);
            childIdsVec.push_front(itemFindId(pNewItem));  //deleteChildRowIdList()从每个最下层节点依次删除
            getTreeAllChildIds(pNewItem,childIdsVec);
        }
    }
}

/**
 * @brief setIsChecked  设置是否显示复选框
 * @param isChecked  是否勾选
 */
void GY_TreeView::setIsChecked(const bool isChecked)
{
    m_isCheckable = isChecked;
    if(m_isCheckable)
    {
        for(int i=0;i<((QStandardItemModel*)this->model())->rowCount();i++)
        {
            QStandardItem* pItem = ((QStandardItemModel*)this->model())->item(i);
            pItem->setCheckable(isChecked);
            if(pItem->hasChildren())
            {
                pItem->setTristate(isChecked);
                setAllChildChecked(pItem,isChecked); //设置所有节点的选择状态
            }
        }
    }
}

/**
 * @brief setAllChildChecked 设置所有节点的选择状态
 * @param pItem 子节点是item
 */
void GY_TreeView::setAllChildChecked(QStandardItem * const pItem, const bool isChecked)
{
    if(nullptr==pItem)
    {
        return;
    }
    for(int i=0;i<pItem->rowCount();i++)
    {
        QStandardItem* pNewItem = pItem->child(i); //获取子节点item
        pNewItem->setCheckable(isChecked);
        if(pNewItem->hasChildren())
        {
            pNewItem->setTristate(isChecked);
            setAllChildChecked(pNewItem,isChecked); //递归遍历所有节点
        }
    }
}

/**
 * @brief getIsChecked 获取当前是否显示复选框
 * @return 返回是否显示复选框
 */
bool GY_TreeView::getIsChecked()
{
    return m_isCheckable;
}

QVariant GY_TreeView::getCurrentCheckedRowId()
{
    return m_checkedId;
}

/**
 * @brief getCheckedRowIds  获取选中的行id
 * @return 返回全部id
 */
QVector<QVariant> GY_TreeView::getCheckedRowIds()
{
    return m_checkedRowIds;
}

/**
 * @brief getCheckRowDatas  获取选中行数据
 * @return
 */
QMap<QVariant, QVector<QVariant> > GY_TreeView::getCheckRowDatas()
{
    return m_checkRowDatas;
}

/**
 * @brief setRowCheckState  设置复选框选中行状态
 * @param rowId  节点id
 * @param isCheck  是否选中
 * @return 返回该行是否被选中，true选中，false未被选中
 */
bool GY_TreeView::setRowCheckState(const QVariant &rowId, const bool isCheck)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return false;
    }
    QStandardItem* pItem = m_TreeNodeInfo.value(rowId)->pNodeItem; //找出id对应的item
    if(pItem->isCheckable())
    {
        //状态未发生变化不进行后续设置
        auto check_status = pItem->checkState();
        if (isCheck && check_status == Qt::Checked) return true;
        if (!isCheck && check_status == Qt::Unchecked) return true;

        pItem->setCheckState(isCheck?Qt::Checked: Qt::Unchecked);
        setTreeAllChildChecked(pItem,isCheck); //设置子节点全选/全不选
        treeCheckChildChanged(pItem);
        return true;
    }
    return false;
}

/**
 * @brief getRowCheckState  设置复选框选中行状态
 * @param rowId  节点id
 * @return 返回该行是否被选中，true选中，false未被选中
 */
Qt::CheckState GY_TreeView::getRowCheckState(const QVariant &rowId)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return Qt::Unchecked;
    }
    QStandardItem* pItem = m_TreeNodeInfo.value(rowId)->pNodeItem; //找出id对应的item
    return pItem->checkState();
}

/**
 * @brief treeAllChecked  复选框全选/全不选
 * @param ischeck 是否勾选
 */
void GY_TreeView::setTreeAllChecked(const bool isCheck)
{
    if( !((QStandardItemModel*)this->model()) ){ //如果列表为空
        return;
    }
    //遍历map
    foreach (Tree_Node_Info* pTreeInfo, m_TreeNodeInfo) {
        pTreeInfo->pNodeItem->setCheckState(isCheck?Qt::Checked: Qt::Unchecked);//设置item勾选状态
        if(pTreeInfo->pNodeItem->checkState()==Qt::Checked) //如果item勾选，记录id和data
        {
            if(!m_checkedRowIds.contains(pTreeInfo->nodeId))
            {
                m_checkedRowIds.append(pTreeInfo->nodeId);
            }
            if(!m_checkRowDatas.contains(pTreeInfo->nodeId))
            {
                m_checkRowDatas.insert(pTreeInfo->nodeId,pTreeInfo->nodeDatas);
            }
        }
        else //清除记录
        {
            m_checkedRowIds.clear();
            m_checkRowDatas.clear();
        }
    }
}

/**
 * @brief setTreeAllChildChecked  子节点全选/全不选
 * @param pItem 对应的item
 * @param check 是否勾选
 */
void GY_TreeView::setTreeAllChildChecked(QStandardItem *pItem,const bool check)
{
    if(nullptr==pItem)
    {
        return;
    }
    for(int i=0;i<pItem->rowCount();i++) //递归遍历子节点勾选状态
    {
        QStandardItem* pNewItem = pItem->child(i);
        if (pNewItem->checkState() == check?Qt::Checked: Qt::Unchecked) continue;
        setTreeAllChildChecked(pNewItem,check);
    }
    if(pItem->isCheckable())
    {
        pItem->setCheckState(check?Qt::Checked: Qt::Unchecked);//设置item勾选状态
        QVariant id = itemFindId(pItem);
        if(pItem->checkState()==Qt::Checked)//如果item勾选，记录id和data
        {
            m_checkedId = id;
            if(!m_checkedRowIds.contains(id))
            {
                m_checkedRowIds.append(id);
            }
            if(!m_checkRowDatas.contains(id))
            {
                m_checkRowDatas.insert(id,m_TreeNodeInfo.value(id)->nodeDatas);
            }
        }
        else
        {
            m_checkedRowIds.removeAll(id);
            m_checkRowDatas.remove(id);
        }
    }
}

/**
 * @brief treeCheckChildChanged 根据子节点改变，更改父节点
 * @param pItem 对应的item
 */
void GY_TreeView::treeCheckChildChanged(QStandardItem *pItem)
{
    if(nullptr==pItem)
    {
        return;
    }
    QVariant id = itemFindId(pItem);
    if(pItem->checkState()==Qt::Checked)
    {
        m_checkedId = id;
        if(!m_checkedRowIds.contains(id))
        {
            m_checkedRowIds.append(id);
        }
        if(!m_checkRowDatas.contains(id))
        {
            m_checkRowDatas.insert(id,m_TreeNodeInfo.value(id)->nodeDatas);
        }
    }
    else
    {
        m_checkedRowIds.removeOne(id);
        m_checkRowDatas.remove(id);
    }
    Qt::CheckState siblingState = checkSibling(pItem); //检测item兄弟节点情况
    QStandardItem* pParentItem = pItem->parent(); //获取父节点
    if(nullptr==pParentItem)
    {
        return;
    }
    if(siblingState == Qt::Checked){
        pParentItem->setCheckState(pItem->checkState() == Qt::Checked ? Qt::Checked : Qt::PartiallyChecked);
    }
    else if (siblingState == Qt::Unchecked){
        pParentItem->setCheckState(pItem->checkState() == Qt::Unchecked ? Qt::Unchecked : Qt::PartiallyChecked);
    }
    else{
        pParentItem->setCheckState(Qt::PartiallyChecked);
    }
    treeCheckChildChanged(pParentItem);
}

/**
 * @brief checkSibling  检测兄弟节点情况
 * @param pItem 对应的item
 * @return 返回勾选状态
 */
Qt::CheckState GY_TreeView::checkSibling(QStandardItem *pItem)
{
    QStandardItem* pParentItem = pItem->parent();
    if(nullptr==pParentItem)
    {
        return pItem->checkState();
    }
    int checkCount(0),unCheckCount(0);
    Qt::CheckState state;
    for(int i=0;i<pParentItem->rowCount();i++)
    {
        QStandardItem* pSiblingItem = pParentItem->child(i);
        state = pSiblingItem->checkState();
        if(Qt::PartiallyChecked==state)
        {
            return Qt::PartiallyChecked;
        }
        else if(Qt::Unchecked==state)
        {
            ++unCheckCount;
        }
        else
        {
            ++checkCount;
        }
        if(checkCount>0 && unCheckCount>0)
        {
            return Qt::PartiallyChecked;
        }
    }
    if(unCheckCount>0)
    {
        return Qt::Unchecked;
    }
    return Qt::Checked;
}

/**
 * @brief itemFindId 根据item查找对应的id
 * @param pItem 对应的item
 * @return 返回item对应的id
 */
QVariant GY_TreeView::itemFindId(QStandardItem *pItem)
{
    QVariant id;
    foreach (Tree_Node_Info* tableInfoIter, m_TreeNodeInfo) {
        if(tableInfoIter->pNodeItem->parent()==pItem->parent() && tableInfoIter->pNodeItem->row()==pItem->row())
        {
            id = tableInfoIter->nodeId;
        }
    }
    return id;
}

/**
 * @brief getParentId 获取父节点id
 * @param id 行id
 * @return 返回父节点id
 */
QVariant GY_TreeView::getParentId(const QVariant id)
{
    if(!m_TreeNodeInfo.contains(id))
    {
        return QVariant();
    }
    QStandardItem* pItem = m_TreeNodeInfo.value(id)->pNodeItem;
    QVariant parentId;
    if(pItem->parent())
    {
        parentId = itemFindId(pItem->parent());
    }
    return parentId;
}

/**
 * @brief getDirectChildrenId 获取直接子节点id
 * @param id 行id
 * @return 返回直接子节点id列表
 */
QVector<QVariant> GY_TreeView::getDirectChildrenId(const QVariant id)
{
    if(!m_TreeNodeInfo.contains(id))
    {
        return QVector<QVariant>();
    }
    QStandardItem* pItem = m_TreeNodeInfo.value(id)->pNodeItem;
    QVector<QVariant> DirectChildrenId;
    for (int i = 0; i < pItem->rowCount(); ++i) {
        DirectChildrenId.push_back(itemFindId(pItem->child(i)));
    }

    return DirectChildrenId;
}


/**
 * @brief addChildId 添加子节点Id
 * @param id 行id
 * @return 返回子节点id
 */
QVariant GY_TreeView::addChildId(const QVariant id)
{
    if(!m_TreeNodeInfo.contains(id))
    {
        return QVariant();
    }
    QVariant childId;
    int i=0;
    while(1)
    {
        childId = id.toString() + "." + QString("%1").arg(i);
        if(!m_TreeNodeInfo.contains(childId))
        {
            break;
        }
        i++;
    }
    return childId;
}

/**
 * @brief getNodeType 根据节点查找类型
 * @param rowId 行Id
 * @return 返回对应type
 */
QVariant GY_TreeView::getNodeType(const QVariant rowId)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return QVariant();
    }
    return m_TreeNodeInfo.value(rowId)->nodeIconType;
}

/**
 * @brief triggerRename 重命名
 * @param regExp 输入格式
 */
void GY_TreeView::triggerRename(const QString &regExp)
{
    m_regExp = regExp;
    QStandardItem* pItem = m_TreeNodeInfo.value(m_selectRowId)->pNodeItem;
    m_oldName = pItem->text();
    m_oldItem = pItem;
    QModelIndex index = ((QStandardItemModel*)this->model())->indexFromItem(pItem);
    this->edit(index); //将当前节点设为可编辑模式
}

/**
 * @brief setNodeEditeState 设置节点是否可更改
 * @param rowId 行id
 * @param isEdited 是否可更改
 */
void GY_TreeView::setRowEditeState(const QVariant &rowId, int FColumn, int Tcloumn, const bool isEdited)
{
    if(m_TreeNodeInfo.contains(rowId)&& FColumn>=0 && FColumn<=Tcloumn)
    {
        QStandardItem* pItem = m_TreeNodeInfo.value(rowId)->pNodeItem;
        QStandardItem* parentItem;
        if(pItem->parent())
        {
            parentItem = pItem->parent();
        }
        else {
            parentItem = ((QStandardItemModel*)this->model())->invisibleRootItem();
        }
        if(Tcloumn>((QStandardItemModel*)this->model())->columnCount()-1)
        {
            Tcloumn = ((QStandardItemModel*)this->model())->columnCount()-1;
        }

        for(int i=FColumn;i<Tcloumn;i++)
        {
            parentItem->child(pItem->row(),i)->setEditable(isEdited);
        }
    }
}

/**
 * @brief creatNewNodeName 创建新节点名称
 * @param nodeName 节点名称类型
 * @return 返回计数后的节点名称
 */
QString GY_TreeView::creatNewNodeName(const QString &nodeName)
{
    int i=1;
    QString newNodeName;
    while(1)
    {
        newNodeName = nodeName + "_" + QString("%1").arg(i);
        if(!m_nodeNameList.contains(newNodeName))
        {
            m_nodeNameList.append(newNodeName);
            break;
        }
        i++;
    }
    return newNodeName;
}

/**
 * @brief getRowIdIndex 获取行节点的索引
 * @param rowId 行ID
 * @return 返回该节点索引
 */
int GY_TreeView::getRowIdIndex(const QVariant &rowId)
{
    if(!m_TreeNodeInfo.contains(rowId))
    {
        return -1;
    }
    QStandardItem* pItem = m_TreeNodeInfo.value(rowId)->pNodeItem;
    QModelIndex index = ((QStandardItemModel*)this->model())->indexFromItem(pItem);
    return index.row();
}

/**
 * @brief setNodeMoveRow 设置节点是否可移动
 * @param isMoved 是否可移动
 */
void GY_TreeView::setNodeMoveRow(const bool isMoved)
{
    setDragEnabled(isMoved);
    setAcceptDrops(isMoved);
    setDropIndicatorShown(isMoved);
    setDragDropOverwriteMode(isMoved);
    setDragDropMode(QAbstractItemView::InternalMove); //设置模式为允许移动
}

/**
 * @brief dragEnterEvent 鼠标拖动进入事件
 * @param event 进入事件
 */
void GY_TreeView::dragEnterEvent(QDragEnterEvent *event)
{
    if(event->mimeData()->hasText() || (event->mimeData()->hasFormat("application/x-dnditemdata")&&m_isAcceptInsertOtherInfo))
    {
        if (event->source() == this) {
            event->setDropAction(Qt::MoveAction);
            event->accept();
        } else {
            event->acceptProposedAction();
        }
    }
    else {
        event->ignore(); //忽略
        QTreeView::dragEnterEvent(event);
    }
}

/**
 * @brief dragMoveEvent 拖拽移动事件
 * @param event 移动事件
 */
void GY_TreeView::dragMoveEvent(QDragMoveEvent *event)
{
    QModelIndex index = this->indexAt(event->pos());
    if((event->mimeData()->hasText() || (event->mimeData()->hasFormat("application/x-dnditemdata")&&m_isAcceptInsertOtherInfo)))
    {
        if(index.isValid())
        {
            QStandardItem* pDestItem = ((QStandardItemModel*)this->model())->itemFromIndex(index); //目标节点
            m_destId = itemFindId(pDestItem); //找到目标节点Id
            if (event->source() == this) {
                event->setDropAction(Qt::MoveAction);
                event->accept();
            } else {
                event->acceptProposedAction();
            }
        }
    }
    else
    {
        event->ignore();
        QTreeView::dragMoveEvent(event);
    }
}

/**
 * @brief moveSrcDestIds 将源节点移动至目标节点下
 * @param SrcId 源节点id
 * @param DestId 目标节点id
 */
void GY_TreeView::moveSrcDestIds(const QVariant &SrcId, const QVariant &DestId)
{
    QVariant childId = addChildId(DestId); //获取新增节点id 临时记录
    //在目标节点下新增一行，并将选择行的相关数据添加进去
    QVector<QVariant> nodeDatas = m_TreeNodeInfo.value(SrcId)->nodeDatas;
    QVariant nodeIconType = m_TreeNodeInfo.value(SrcId)->nodeIconType;
    addRowData(childId,nodeDatas,DestId,nodeIconType);
    QStandardItem* pSrcItem = m_TreeNodeInfo.value(SrcId)->pNodeItem; //获取源节点
    QStandardItem* pDestItem = m_TreeNodeInfo.value(childId)->pNodeItem; //获取目标节点
    if(pSrcItem->hasChildren()) //如果源节点有子节点
    {
        moveItems(pDestItem,pSrcItem,pSrcItem->columnCount()); //将源节点的子节点一起移到目标节点下
    }
    deleteRow(SrcId); //删除原选择行id
    pDestItem->setData(SrcId,Qt::UserRole);

    m_TreeNodeInfo.value(childId)->nodeId = SrcId;
    m_TreeNodeInfo.value(childId)->nodeParentId = DestId;
    m_TreeNodeInfo.insert(SrcId,m_TreeNodeInfo.value(childId));
    m_IconIdMap.insert(SrcId,m_IconIdMap.value(childId));
    m_TreeNodeInfo.remove(childId);
    m_IconIdMap.remove(childId);
    m_nodeNameList.append(m_TreeNodeInfo.value(SrcId)->nodeDatas.at(0).toString());

    setRowExpendState(DestId,true);
}

/**
 * @brief moveSrctoDestIndex 将源节点移动至目标节点的位置
 * @param SrcId 源节点id
 * @param DestId 目标节点id
 */
void GY_TreeView::moveSrctoDestIndex(const QVariant &SrcId, const QVariant &DestId)
{
    QVector<QVariant> srcData = m_TreeNodeInfo.value(SrcId)->nodeDatas;
    QVariant srcType = m_TreeNodeInfo.value(SrcId)->nodeIconType;
    QVariant parentId = getParentId(DestId);
    if(parentId.isNull())
    {
        parentId = itemFindId(((QStandardItemModel*)this->model())->item(0,0));
    }
    QVariant temId = addChildId(parentId); //获取新增节点id 临时记录
//    int index = getRowIdIndex(DestId);

//    insterRowData(temId,srcData,index,parentId,srcType);
//    QStandardItem* pSrcItem = m_TreeNodeInfo.value(SrcId)->pNodeItem; //获取源节点
//    QStandardItem* pDestItem = m_TreeNodeInfo.value(temId)->pNodeItem; //获取目标节点

//    if(pSrcItem->hasChildren()) //如果源节点有子节点
//    {
//        moveItems(pDestItem,pSrcItem,pSrcItem->columnCount()); //将源节点的子节点一起移到目标节点下
//    }
//    deleteRow(SrcId); //删除原选择行id

//    m_TreeNodeInfo.value(temId)->nodeId = SrcId;
//    m_TreeNodeInfo.value(temId)->nodeParentId = DestId;
//    m_TreeNodeInfo.insert(SrcId,m_TreeNodeInfo.value(temId));
//    m_IconIdMap.insert(SrcId,m_IconIdMap.value(temId));
//    m_TreeNodeInfo.remove(temId);
//    m_IconIdMap.remove(temId);
//    m_nodeNameList.append(m_TreeNodeInfo.value(SrcId)->nodeDatas.at(0).toString());

//    setRowExpendState(DestId,true);
}

/**
 * @brief setAccecptOtherViewInsertView 接收其他界面传入数据
 * @param isAccept 是否接收数据
 */
void GY_TreeView::setAccecptOtherViewInsertInfo(const bool isAccept)
{
    m_isAcceptInsertOtherInfo = isAccept;
}

/**
 * @brief setRowMoveUpDown 设置行上/下移
 * @param rowId 行id
 * @param isUp true为上移，false为下移
 */
bool GY_TreeView::setRowMoveUpDown(const QVariant &rowId, const bool isUp)
{
    if(!m_TreeNodeInfo.contains(rowId) || !((QStandardItemModel*)this->model()))
    {
        return false;
    }
    bool isExpend = getExpentState(rowId); //获取节点展开状态
    QStandardItem* pItem = m_TreeNodeInfo.value(rowId)->pNodeItem;
    int row = pItem->row();
    int toRow = row+1;
    if(isUp)
    {
        if(row==0) {
            return false;
        }
        toRow = row-1;
    }
    if(pItem->parent())
    {
        QStandardItem* parentItem = pItem->parent();
        if(!isUp && row==parentItem->rowCount()-1)
        {
            return false;
        }
        QList<QStandardItem *> listItem = parentItem->takeRow(row);
        parentItem->insertRow(toRow,listItem);
    }
    else {
        if(!isUp && row==((QStandardItemModel*)this->model())->rowCount()-1)
        {
            return false;
        }
        QList<QStandardItem *> listItem = ((QStandardItemModel*)this->model())->takeRow(row);
        ((QStandardItemModel*)this->model())->insertRow(toRow,listItem);
    }

    setCurrentIndex(pItem->index()); //设置当前选择行
    this->selectionModel()->select(pItem->index(),QItemSelectionModel::Select | QItemSelectionModel::Rows); //设置行选择模式
    setRowExpendState(rowId,isExpend); //设置行单层展开模式
    return true;
}

/**
 * @brief dropEvent 鼠标拖拽释放事件
 * @param event 放置事件
 */
void GY_TreeView::dropEvent(QDropEvent *event)
{
    if(event->mimeData()->hasText() || event->mimeData()->hasFormat("application/x-dnditemdata"))
    {
//        QModelIndex index = this->indexAt(event->pos());
//        if(index.isValid())
//        {
            if (event->source() == this) //自己内部数据变动
            {
                if(m_selectRowId!=m_destId)
                {
                    emit sendSrcDestIds(m_selectRowId,m_destId);
                }
                event->setDropAction(Qt::MoveAction);
                event->accept();
            }
            else //外部传入数据
            {
                if(event->mimeData()->hasFormat("application/x-dnditemdata") && m_isAcceptInsertOtherInfo)
                {
                    QByteArray itemData = event->mimeData()->data("application/x-dnditemdata");
                    QDataStream dataStream(&itemData, QIODevice::ReadOnly);
                    QVariant objectGuid;
                    QString objectName;
                    QVariant objectType;
                    QString dropAreaName;
                    dataStream >> objectGuid >> objectName >> objectType >> dropAreaName;
                    if(m_destId!=objectGuid)
                    {
                        emit sendDropEvent(m_destId, objectGuid, objectName, objectType, dropAreaName);
                    }
                }
                event->acceptProposedAction();
            }
//        }

    }
    else {
        event->ignore();
    }
    QTreeView::dropEvent(event);
}

/**
 * @brief mousePressEvent 鼠标单击空白事件
 * @param event 点击事件
 */
void GY_TreeView::mousePressEvent(QMouseEvent *event)
{
    QModelIndex index = this->indexAt(event->pos());
    if(!index.isValid())
    {
        m_selectRowId = QVariant();
        m_getselectRowIdsVec.clear();
        setCurrentIndex(index); //实现空白处取消选择
    }
    else {
        QStandardItem* pItem = ((QStandardItemModel*)this->model())->itemFromIndex(index);
        if(!pItem->parent())
        {
            pItem = ((QStandardItemModel*)this->model())->item(index.row(),0);
        }
        else {
            pItem = pItem->parent()->child(index.row(),0);
        }
        m_selectRowId = itemFindId(pItem); //获取选择行id
        m_oldName = pItem->text();
        m_oldItem = pItem;
    }
    //发送界面点击信号
    sendPressRowId(m_selectRowId);
    QTreeView::mousePressEvent(event);
}

/**
 * @brief mouseMoveEvent 鼠标移动事件
 * @param event 移动事件
 */
void GY_TreeView::mouseMoveEvent(QMouseEvent *event)
{
    QModelIndex index = this->indexAt(event->pos());
    if(!index.isValid())
    {
        return;
    }
    else {
        QByteArray itemData;
        QDataStream dataStream(&itemData, QIODevice::WriteOnly);
        QVariant rowType = m_TreeNodeInfo.value(m_selectRowId)->nodeIconType;
        dataStream << m_selectRowId << m_oldName << rowType << this->parent()->objectName();

        QMimeData *pMimeData = new QMimeData;
        pMimeData->setData("application/x-dnditemdata", itemData);
        QDrag *pDrag = new QDrag(this);
        pDrag->setMimeData(pMimeData);

        //进入drag的拖拽消息循环，依次触发dragEnterEveny、dragMoveEvent、dropEvent消息
        if(pDrag->exec(Qt::MoveAction)==Qt::MoveAction)
        {
        }
    }
    QTreeView::mouseMoveEvent(event);
}

/**
 * @brief mouseDoubleClickEvent 鼠标双击事件
 * @param event 双击事件
 */
void GY_TreeView::mouseDoubleClickEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton)
    {
        QModelIndex index = this->indexAt(event->pos());
        if(!index.isValid())
        {
            setCurrentIndex(index); //实现空白处取消选择
        }
        else {
            m_doubleClickedId = m_selectRowId;
        }
        QTreeView::mouseDoubleClickEvent(event);
    }
}

/**
 * @brief receiveClicked 单击接收事件
 * @param index 当前index
 */
void GY_TreeView::receiveClicked(const QModelIndex &index)
{
    QStandardItem* pItem = ((QStandardItemModel*)this->model())->itemFromIndex(index); //获得当前点击的item
    QVariant rowId;

    if(!pItem->parent())
    {
        pItem = ((QStandardItemModel*)this->model())->item(index.row(),0);
        rowId = itemFindId(pItem);
    }
    else {
        pItem = pItem->parent()->child(index.row(),0);
        rowId = itemFindId(pItem);
        QVariant parentId = m_TreeNodeInfo.value(rowId)->nodeParentId;
        emit selectChangeEvent(index.row(),parentId); //发送选择改变信号
    }
    emit selectChangeEvent(rowId);

    if(pItem->isCheckable()) //如果item是可勾选的
    {
        Qt::CheckState state = pItem->checkState();
        if(pItem->isTristate()) //判断是否是三态
        {
            if(state!=Qt::PartiallyChecked)
            {
                setTreeAllChildChecked(pItem,state==Qt::Checked?true:false);
            }
        }
        treeCheckChildChanged(pItem);
        emit checkStateChangeEvent(rowId,state);
    }
}

/**
 * @brief receiveExpend 接收展开信号
 * @param index 当前index
 */
void GY_TreeView::receiveExpend(const QModelIndex &index)
{
    QStandardItem* pItem = ((QStandardItemModel*)this->model())->itemFromIndex(index); //获得当前点击的item
    QVariant rowId = itemFindId(pItem);
    emit expendRowId(rowId);
}

/**
 * @brief receiveCollapsed 接收关闭展开信号
 * @param index 当前index
 */
void GY_TreeView::receiveCollapsed(const QModelIndex &index)
{
    QStandardItem* pItem = ((QStandardItemModel*)this->model())->itemFromIndex(index); //获得当前点击的item
    QVariant rowId = itemFindId(pItem);
    emit collapsedRowId(rowId);
}

/**
 * @brief ItemChanged 节点改变响应
 * @param pItem 节点
 */
void GY_TreeView::ItemChanged(QStandardItem *pItem)
{
    if(nullptr==pItem || m_oldName==nullptr || m_oldItem!=pItem)
    {
        return;
    }
    if(!m_regExp.isNull()){
        QRegExp itemRegExp(m_regExp);
        if(!itemRegExp.exactMatch(pItem->text())){
            pItem->setText(m_oldName);
            return;
        }
    }
    if(m_oldName!=pItem->text()){
        if(m_nodeNameList.contains(pItem->text())){
            pItem->setText(m_oldName);
            return;
        }
        if(m_nodeNameList.contains(m_oldName)){
            int index = m_nodeNameList.indexOf(m_oldName);
            m_nodeNameList.replace(index,pItem->text());
        }

        QVariant rowId = itemFindId(pItem);
        m_TreeNodeInfo.value(rowId)->nodeDatas[0] = pItem->text();
        emit sendNames(rowId, m_oldName); //发送旧名称及新名称
        m_oldName=nullptr;
    }
}

/**
 * @brief getRowIdsFromName 根据名称获取id
 * @param nameList 名称集
 * @return 返回id集
 */
QVector<QVariant> GY_TreeView::getRowIdsFromName(const QStringList &nameList)
{
    QVector<QVariant> allRowIds = getAllRowIds(); //获取所有行ID
    QVector<QVariant> selectIds; //记录对应的行id
    for (int i=0;i<nameList.size();i++)
    {
        QString graphItemName = nameList[i]; //获取传入的单个图元名称
        for(int i=0;i<allRowIds.size();i++)
        {
            QString idName = getRowData(allRowIds[i]).at(0).toString(); //获取行数据
            if(graphItemName==idName) //如果名称与行数据相同
            {
                selectIds<< allRowIds[i];
            }
        }
    }
    return selectIds;
}
